/*
 * Copyright (c) Ulrich Hilger, http://dev.uhilger.de, all rights reserved.
 *
 * Published under the terms and conditions of the Apache License 2.0,
 * see http://www.apache.org/licenses/LICENSE-2.0
 */

package de.uhilger.servicehub.server;

import de.uhilger.servicehub.model.DatabaseServer;
import de.uhilger.servicehub.ServiceHub;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.util.logging.Level;
import org.apache.derby.drda.NetworkServerControl;

/**
 * An embedded Derby database server.
 *
 * @author Ulrich Hilger, <a href="http://dev.uhilger.de" target="_blank">http://dev.uhilger.de</a>
 * @author Published under the terms and conditions of
 * the <a href="http://www.apache.org/licenses/LICENSE-2.0" target="_blank">Apache License 2.0</a>
 */
public class NetworkDerbyServer implements DatabaseServer {

  private static final String VERSION = "Version: ";
  private static final String BUILD = "Build: ";
  private static final String DB_SERVER_NAME = "Derby Network Server";

  private int portNum;
  private NetworkServerControl serverControl;
  private PrintWriter pw;

  /**
   * Create a new object of class NetworkDerbyServer
   *
   * @param pw  writer for server messages
   */
  public NetworkDerbyServer(int port, PrintWriter pw) {

    // this.portNum = port;
    this.pw = pw;
    this.portNum = port;
    try {
      serverControl = new NetworkServerControl(InetAddress.getByName("localhost"), port);
      pw.println("Derby Network Server created");
      ServiceHub.log("Derby Network Server created", getClass(), Level.FINEST);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  /**
   * trace utility of server
   *
   * @param onoff  true to switch on, false to switch off
   */
  public void trace(boolean onoff) {
    try {
      serverControl.trace(onoff);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  /**
   * Try to test for a connection
   * Throws exception if unable to get a connection
   */
  public void testForConnection()
    throws Exception {
    serverControl.ping();
  }

  /**
   * Shutdown the NetworkServer
   */
  public void shutdown() {
    try {
      ServiceHub.log("stopping derby", getClass(), Level.FINEST);
      serverControl.shutdown();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  /**
   * Start Derby Network server
   */
  public void start(int port) {
    try {
      ServiceHub.log("starting derby", getClass(), Level.FINEST);
      if(portNum != port) {
        serverControl = new NetworkServerControl(InetAddress.getByName("localhost"), port);
      }
      serverControl.start(pw);
      //String myinfo = serverControl.getRuntimeInfo();
      //pw.println(myinfo);
      //ServiceHub.log("derby info " + myinfo, getClass(), Level.FINEST);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  public String getDatabaseServerInfo() {
    String info = "";
    try {
      info = serverControl.getSysinfo();

      int versionStart = info.indexOf(VERSION) + VERSION.length();
      int versionEnd = info.indexOf(" ", versionStart);
      int buildStart = info.indexOf(BUILD) + BUILD.length();
      int buildEnd = info.indexOf(" ", buildStart);

      String version = info.substring(versionStart, versionEnd);
      String build = info.substring(buildStart, buildEnd);

      info = DB_SERVER_NAME + ", " + VERSION + version + ", " + BUILD + build;

      ServiceHub.log("db server info: " + info, getClass(), Level.FINEST);
      //info = serverControl.getRuntimeInfo();
    } catch (Exception ex) {
      info = ex.getMessage();
      ServiceHub.logStackTrace(ex, getClass());
    }
    return info;
  }
}
